﻿using Dyao.Book.Application.Abstractions;
using Dyao.Book.Application.Extensions;
using Dyao.Book.Contract;
using Dyao.Book.Repository.Abstractions;
using Foundation.Caching;
using Foundation.Core;
using Foundation.Uow;

namespace Dyao.Book.Application
{
    public class BookApplication : BaseApplication, IBookApplication
    {
        private readonly IBookRepository _bookRepository;

        private readonly IDistributedMultiLevelCache _distributedMultiLevelCache;

        public BookApplication(IBookRepository bookRepository,
           IDistributedMultiLevelCache distributedMultiLevelCache)
        {
            _bookRepository = bookRepository;
            _distributedMultiLevelCache = distributedMultiLevelCache;
        }

        /// <inheritdoc cref="IBookApplication.GetBookAsync"/>
        public async Task<BookDto> GetBookAsync(string bookId, CancellationToken cancellationToken)
        {
            using (var uowMgr = UnitOfWorkManager.Begin(isReadDb: true))
            {
                var books = await _bookRepository.GetListByIdsAsync(new List<string>() { bookId }, b => new BookDto
                {
                    BookId = bookId,
                    BookAuthor = b.Author,
                    BookDesc = b.Description,
                    BookName = b.Title,
                    BookPic = b.CoverPicture,
                    Category = b.Category,
                    SubCategory = b.SubCategory,
                }, cancellationToken);

                if (books.IsNullOrEmpty())
                    throw new BusinessException("未找到相关书籍信息.");

                return books.FirstOrDefault();
            }
        }

        /// <inheritdoc cref="IBookApplication.GetBookSelectItemsAsync"/>
        public async Task<List<SelectItem>> GetBookSelectItemsAsync(CancellationToken cancellationToken)
        {
            using (var uowMgr = UnitOfWorkManager.Begin(isReadDb: true))
            {
                var books = await _distributedMultiLevelCache.GetOrAddAsync(CacheConstants.BookSelectItemCache, async () =>
                {
                    var books = await _bookRepository.GetAllListAsync(b => new SelectItem()
                    {
                        Label = $"{b.Title}({b.Author})",
                        Value = b.ID
                    }, cancellationToken);

                    return books;
                }, TimeSpan.FromMinutes(30));

                return books.ToList();
            }
        }
    }
}
